package mobile;

import item.Item;
//import java.util.Arrays;
import core.Core;

public class Mobile 
{
	private int mHp;
	private int mHpMax;
	private int mMana;
	private int mManaMax;
	private int mDamage;
	private int mAc;
	private int mTempAcBonus;
	private int mAttackBonus;
	private int mTempAttackBonus;
	private int mLevel;
	private int mXp;
	private int mGold;

	private int[] mStats={0,1,2,3,4,5};
	private int[] mMaxStats={0,1,2,3,4,5};
	private static String[] mStatNames =
	{"Strength",
		"Dexterity",
		"Constitution", 
		"Inteligence", 
		"Wisdom", 
	"Luck"};
	private static String[] mShortStatNames=
	{"Str","Dex", "Con", "Int", "Wis", "Lck"};
	/*
	 * 0 Strength
	 * 1 Dexterity
	 * 2 Constitution
	 * 3 Inteligence
	 * 4 Wisdom
	 * 5 Luck
	 */
	

	private String mName;
	private String mRace;
	private String mClass;


	private Item[] mInventory = new Item[10];


//	Initialize this object
	private void defaultMob() 	
	{
		for (int i=0;i<mInventory.length;i++)
			mInventory[i]=null; // Empty inventory
		mAttackBonus=10;
		mTempAttackBonus=0;
		mDamage=1;
		mAc=10;
		mTempAcBonus=0;
		mLevel=1;
		mXp=0;
		mGold=0;
		mName="Unnamed";
		mRace="noob";
		mClass="Luser";

	}

	public Mobile(int startLevel, String startClass, String startRace)
	{
		defaultMob();
		mLevel=startLevel;
		mClass=startClass;
		mRace=startRace;
		mHp=mHpMax=10;
		mMana=mManaMax=0;
		// Generate the rest of the stats...
	}

	/* 
	 * Generate a new player with random stats.
	 */
	public Mobile( String startRace )
	{
		defaultMob();
		generateStats(startRace);
		setRace(startRace);
		// initInventory();	
		mGold=100;
		mLevel=1;
		mXp=0;
	}
	// TODO: actualy save something..
	// Returns 0 if ok, 1 on failure.
	public int saveMe()
	{
		return 0;
	}

	public String getStats()
	{
		String result="";
		for (int i = 0; i < mStats.length; i++)
			result += mShortStatNames[i] + ": " +  mStats[i] + "\n"; 
		
		return result;
	}

	public int getHp()
	{
		return mHp;
	}

	public int getAc()
	{
		return mAc;
	}
	public int getHpMax()
	{
		return mHpMax;
	}

	public void setHp(int newHp)
	{
		mHp=newHp;
	}

	public int getMana()
	{
		return mMana;
	}

	public int getManaMax()
	{
		return mManaMax;
	}



	/* 
	 * this should not be available for external use
	 * 
	 * public void setHpMax(int newHpMax)
	 *
	 * {
	 * 	mHpMax=newHpMax;
	 * }
	 */


	private int raiseMana()
	{
		return Core.dice(mStats[3],1)+Core.dice(mStats[4],1);
	}

	private int raiseHp()
	{
		// TODO; add function so that a warrior gains more hp
		// then a wizard.
		return mStats[2]+Core.dice(mStats[2],1);
	}

	public int hitMe(int damage)
	{
		int tmp = (( mHp - damage ) < 0 ) ? mHp : ( mHp - damage );
		mHp -= tmp;
		// Return damage taken
		// TODO: Check for death
		return tmp;
	}

	public int healHp(int healing)
	{
		int tmp=( (mHp + healing) > mHpMax ) ? mHpMax: (mHp + healing);
		mHp += tmp;
		// Return the amount of hp healed.
		return tmp;
	} 
	
	// Temporary add some hp.
	public void buffHp(int buff)
	{
		mHp += buff;
	}

	// Returns 0 if we had mana, or 1 if we didnt have enough mana.
	public int useMana(int mana)
	{
		int tmp = mMana - mana;
		if ( tmp >= 0 )
		{
			mMana -= mana;
			return 0;
		}
		else
			return 1;

	}

	public int gainMana(int mana)
	{
		int tmp= ( (mMana + mana) > mManaMax ) ? mManaMax: (mMana+mana);
		mMana += tmp;
		return tmp;
	}


	public void setName(String newName)
	{
		mName=newName;
	}

	public String getName()
	{
		return mName;
	}

	public String getRace()
	{
		return mRace;
	}

	public void setRace(String newRace)
	{
		mRace=newRace;
	}

	public void setClass(String newClass)
	{
		// TODO: fix this so that all mana using classes gets start mana.
		mClass=newClass;
		if (newClass.equals("Wizard") ) 
		{
			mMana=mManaMax=raiseMana();
		}
	}

	public void generateStats(String race)
	{
		/*
		 * TODO: Read the race from .xml file, 
		 * loop throughn the stats.
		 * fielss: eyes:dices:mod , ex 3d6+1
		 * store the max values somewhere for the level up function.
		 */

		// Maybe save the real values somewhere if we need to
		// modify them temporary..

		for (int i = 0; i< mStats.length ; i++)
			mStats[i]=Core.dice(6,3);
		for (int i = 0; i< mMaxStats.length ; i++)
			mMaxStats[i]=18;
		/*	
		mStrength=dice(6,3);
		mDexterity=dice(6,3);
		mConstitution=dice(6,3);
		mInteligence=dice(6,3);
		mWisdom=dice(6,3);
		mLuck=dice(6,3);

		mMaxStrength=18;
		mMaxDexterity=18;
		mMaxConstitution=18;
		mMaxInteligence=18;
		mMaxWisdom=18;
		mMaxLuck=18;
		 */

		mHpMax=mHp=raiseHp();
	}
	public int getLevel()
	{
		return mLevel;
	}

	public void addXp(int amount)
	{
		mXp+=amount;

	}

	public int getXp()
	{
		return mXp;
	}

	public int levelUp()
	{
		// Check if we can level up, return 0 if not.
		if (mXp < (1024 << (mLevel-1)) )
			return 0;
		// Raise on random stat, if not already at max.
		int rndStats[] = new int[mStats.length];
		for (int i=0;i<rndStats.length;i++)
			rndStats[i]=i;

		// shuffle the array.
		for (int i = 0; i<rndStats.length; i++)
		{

			int temp = rndStats[i];
			int randomPosition = Core.nextInt(rndStats.length);
			rndStats[i]=rndStats[randomPosition];
			rndStats[randomPosition]=temp;
		}

		for (int i = 0 ; i < rndStats.length; i ++)
		{
			if ( mStats[rndStats[i]] < mMaxStats[rndStats[i]] )
			{
				mStats[rndStats[i]]++;
				System.out.println("Raised stat " + 
						mStatNames[rndStats[i]] );
				break;
			}
		}



		// Raise the level	
		mLevel++;

		// Raise hp
		// TODO: class modifier on hp raise?
		int hpRaise=raiseHp();
		mHpMax+=hpRaise;
		mHp+=hpRaise;

		// if we have mana, raise it as well:
		System.out.println("Gained one level, and " + hpRaise + "hp");
		if (mManaMax!=0)
		{
			int mpRaise=raiseMana();
			mManaMax+=mpRaise;
			mMana+=mpRaise;
			System.out.println("Gained " + mpRaise + " mana");
		}
		return 1;
	}

	/* 
	 * returns 1 if the item didnt get room in the inventory
	 * otherwise it returns 0
	 */
	public int getItem(Item newItem)
	{
		int i;
		for ( i=0; i< mInventory.length;i++)
		{
			if (mInventory[i] == null)
			{
				mInventory[i] = newItem;
				break;
			}

		}
		if ( i < mInventory.length)	
			return 0;
		else
			return 1;


	}

	public void printInventory()
	{
		int i;
		for (i = 0; i < mInventory.length; i++)
		{
			if ( mInventory[i] == null)   
				System.out.println(i + " Empty")  ;
			else
			{
				String eqipped = "-";
				if (mInventory[i].getEquipped() != 0 )
					eqipped="*";

				System.out.println(i + " " + mInventory[i].getName() + " " + eqipped);

			}
		}
	}

	public int equip (int inventoryNumber )
	{
		int slot=0;
		//try 
		if ( mInventory[inventoryNumber] != null )
		{
			slot= mInventory[inventoryNumber].getSlot();
		}
		else
			return 0; // item not in inventory

		if (  mInventory[inventoryNumber].equipAccess(this) == 0 )	
			return 0; // we cant equip this


		// Loop through the inventory and check for equipped items in
		// that slot.
		for (int item = 0; item < mInventory.length; item ++)
		{
			if ( mInventory[item]==null)
			{
				break;
			}
			if ( mInventory[item].getEquipped() == slot)	
			{
				unEquip(item);
				break;
			}
		}	
		// Modify ac and/or attack bonus
		mTempAttackBonus+= mInventory[inventoryNumber].getAttackBonus();
		mTempAcBonus += mInventory[inventoryNumber].getAcBonus();
		return mInventory[inventoryNumber].equip();

	}
	
	public void unEquip(int inventoryNumber)
	{
		if ( mInventory[inventoryNumber] != null) 
		{
			mTempAttackBonus -= mInventory[inventoryNumber].getAttackBonus();
			mTempAcBonus -= mInventory[inventoryNumber].getAcBonus();
			mInventory[inventoryNumber].unEquip();
			mInventory[inventoryNumber]=null;
		}
	}

	public int getDamage() {
		return mDamage;
	}

	public void setDamage(int damage) {
		mDamage = damage;
	}

	public int getAttackBonus() {
		return mAttackBonus + mTempAttackBonus;
	}
	
	public int getRealAttackBonus()
	{
		return mAttackBonus;
	}
	
	public void addRealAttackBonus(int bonus)
	{
			mAttackBonus += bonus;
	}

	public void addAttackBonus(int bonus)
	{
		mTempAttackBonus+=bonus;
	}
	public void setAttackBonus(int bonus) {
		mAttackBonus = bonus;
	}

	public int getGold() {
		return mGold;
	}

	public void setGold(int gold) {
		mGold = gold;
	}

	public String getMClass() {
		return mClass;
	}

	public int getTempAttackBonus() {
		return mTempAttackBonus;
	}

	public void setTempAttackBonus(int tempAttackBonus) {
		mTempAttackBonus = tempAttackBonus;
	}

	public String getCombatStatus()
	{
		String res="";
		res+="Base AC: " + mAc  + " Bonus Ac: "+ mTempAcBonus + " Total Ac :" + getAc() + "\n" +
		"Base Atk: " + mAttackBonus + " Bonus Attack: " + mTempAttackBonus +" Total atk: "+ getAttackBonus(); 
		return res;
	}

}



